Шаг 3. Решаем конфликт с помощью командной строки

Для начала создадим новую ветку. В этом раз мы будем использовать модель ветвления TBD (Trunk Based Development). Здесь под каждую задачу есть своя ветка. Выполнил задачу — удалил ветку.

TBD — модель ветвления, при которой ветки живут недолго, обычно удаляются после слияния с основной веткой.

Новую ветку назовём conflict/command-line. Создаём её с помощью команды git switch --create conflict/command-line.

Введена команда git switch --create conflict/command-line
Введена команда git switch --create conflict/command-line

Далее вносим изменение: для элемента <h1> установим атрибут class со значением title.

Красная стрелка указывает на добавленный атрибут class для элемента h1
Красная стрелка указывает на добавленный атрибут class для элемента h1

Добавим это изменение в индекс с помощью команды git add --all, а затем зафиксируем его — git commit --message "feat: added the class attribute with the title value for the h1 element".

Введена команда git commit --message
Введена команда git commit --message

Теперь перейдём на ветку main с помощью команды gti switch main.

Введена команда git switch main
Введена команда git switch main

Далее точно так же для элемента <h1> добавим атрибут class, но с другим значением — subheading. Мы специально написали неправильный класс, чтобы можно было заменить на правильный.

Красная стрелка указывает на добавленный атрибут class для элемента h1
Красная стрелка указывает на добавленный атрибут class для элемента h1

Затем добавим это изменение в индекс с помощью команды git add --all, а после зафиксируем с помощью команды git commit --message "feat: added the class attribute with the subheading value for the h1 element".

Введена команда git commit --message
Введена команда git commit --message

Далее выполним слияния. Пропишем команду git merge conflict/command-line --no-ff --message "feat: the conflict/command-line branch was merged into the main branch". Слияние будем выполнять с использованием режима no-fast-forward, чтобы создался коммит слияния.

Введена команда git merge conflict/command-line --no-ff --message
Введена команда git merge conflict/command-line --no-ff --message

Переходим к решению конфликта.

Одна красная стрелка указывает на заголовок с ветки conflict/command-line, а другая — на заголовок с ветки main
Одна красная стрелка указывает на заголовок с ветки conflict/command-line, а другая — на заголовок с ветки main

У нас есть выбор: оставить класс, который был на ветке main, или выбрать класс, который мы добавили на ветке conflict/command-line.

Если вы хотите выбрать изменение, пришедшее с conflict/command-line, воспользуйтесь командой git checkout --their index.html. Если хотите выбрать изменение, которое было на ветке main, используйте команду git checkout --ours index.html.

Опция --their отвечает за входящие изменения, а опция --ours — за принятие изменений, которые были сделаны в текущей (целевой) ветке.

Вместо файла index.html может быть любой другой файл, в котором возник конфликт. Минус этого подхода в том, что если у вас конфликт в нескольких местах, то с помощью этих команд вы не сможете выбрать разные значения для разных участков кода. То есть у вас либо примутся все входящие изменения, либо все те, которые были в текущей ветке.

Если же вам нужно в одном месте принять входящие изменения, а в другом оставить текущие, придётся вручную менять файл. Собственно, как мы это делали в демонстрации, когда затягивали изменение с удалённого репозитория.

Мы выберем входящие изменения. Поэтому воспользуемся командой git checkout --their index.html.

Введена команда git checkout --their index.html
Введена команда git checkout --their index.html

Конфликт решён.

Теперь давайте проверим статус файла с помощью команды git status.

Введена команда git status
Введена команда git status

index.html находится в разделе Unmerged paths, что означает «Не слитые (не замкнутые) пути», а также имеет статус both modified — «Оба модифицированные».

Почему оба, если файл один? Git учитывает не только файл на ветке main, но и на ветке conflict/command-line. Пока мы не добавим данное изменение в индекс и не зафиксируем, он будет считать оба файла модифицированными.

Давайте добавим изменение в индекс с помощью команды git add --all.

Введена команда git add --all
Введена команда git add --all

Теперь у нас есть два варианта развития событий.

  1. Мы можем самостоятельно создать коммит с помощью команды git commit --message "текст коммита".
  2. Мы воспользуемся командой git merge --continue. Она позволяет продолжить слияние, поэтому у нас будет создан коммит с текстом, который мы указывали, когда прописывали команду слияния.

Мы выбираем второй вариант. Пропишем команду git merge --continue. Тут нужно упомянуть: если слияние проходит с использованием режима fast-forward, то вам придётся вручную создавать коммит.

Введена команда git merge --continue
Введена команда git merge --continue

Открылся специальный файл Git — COMMIT_EDITMSG, который позволяет отредактировать текст коммита. Текст коммита нам редактировать не нужно. Поэтому, находясь в файле, просто нажмём сочетание клавиш Ctrl + S, чтобы сохранить изменения, а затем закроем его.

Внизу в этом файле также отмечен наш модифицированный index.html. После его закрытия вернёмся в Git Bash и увидим, что коммит создан.

Красная стрелка указывает на созданный коммит
Красная стрелка указывает на созданный коммит

Далее отправим изменение в удалённый репозиторий с помощью команды git push.

Введена команда git push
Введена команда git push

Изменения отправлены. Теперь мы можем удалить временную ветку conflict/command-line. Для этого воспользуемся командой git branch --delete conflict/command-line.

Введена команда git branch --delete conflict/command-line
Введена команда git branch --delete conflict/command-line

Напоследок посмотрим список всех коммитов и убедимся, что изменения дошли до удалённого репозитория. Для этого пропишем команду git log --oneline.

Введена команда git log --oneline
Введена команда git log --oneline

Сейчас изменения находятся в удалённом репозитории. Также в истории мы можем видеть тот самый коммит, который был сначала извлечён из ветки conflict/command-line, а затем применён к ветке main.